package com.avp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

import android.app.Activity;
import android.media.*;
import android.os.Bundle;
import android.util.Log;

public class Voice {

	private int bufferSize;
	private int tracksize;
	private byte[] buffer;

	private int sampleRate = 11025;
	private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
	
	public Server server;
	public Client client;
	public Thread servert;
	public Thread clientt;

	
	public void startConnection(InetAddress serveraddr, int serverPort)
	{
		
		//setContentView(R.layout.main2);
		
		bufferSize = AudioRecord.getMinBufferSize(sampleRate, 
				channelConfig, audioFormat);
		tracksize=AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
		if (bufferSize>tracksize)
		{
			tracksize=bufferSize;
		}
		if (tracksize>bufferSize)
		{
		bufferSize=tracksize;
		}
		tracksize*=2;
		bufferSize*=2;
		//bufferSize=10000;
		buffer = new byte[bufferSize];
		server=new Server(serveraddr,serverPort);
		servert=new Thread(server);
		servert.start();
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) { }

		// Start the client
		client=new Client(serveraddr,serverPort);
		clientt= new Thread(client);
		clientt.start();
		
	}
	
	public void stopConnection()
	{
	
	server.running=false;
	client.running=false;
	server.close();
	client.close();
	try {
		servert.join();
		clientt.join();
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	}
	

	public class Server implements Runnable {

		public String ServerIP; // 'Within' the emulator!
		public int ServerPort;
		InetAddress serverAddr;
		private AudioTrack player;
		DatagramSocket socket;
		public boolean running=true;
		public Server(InetAddress severaddr, int serverPort)
	{
			
				serverAddr=severaddr;
			this.ServerPort=serverPort;
		
	}
	
		//@Override
		public void run() {
			if (running)
			try {
				
				/* Retrieve the ServerName */
				//InetAddress serverAddr = InetAddress.getByName(ServerIP);

				Log.d("UDP", "S: Connecting...");
				/* Create new UDP-Socket */
				socket = new DatagramSocket(ServerPort);
				player = new AudioTrack(AudioManager.STREAM_VOICE_CALL, sampleRate, 
						channelConfig, audioFormat, tracksize, AudioTrack.MODE_STREAM);
				player.play();
				
				byte[] buf = new byte[tracksize];
				/* Prepare a UDP-Packet that can
				 * contain the data we want to receive */
				DatagramPacket packet = new DatagramPacket(buf, buf.length);
				Log.d("UDP", "S: Receiving...");

				/* Receive the UDP-Packet */
				while(running)
				{
				socket.receive(packet);
				
				player.write(packet.getData(),0,packet.getLength());
				//Log.d("UDP", "S: Received: '" + new String(packet.getData()) + "'");
				Log.d("UDP", "S: Done.");
				} 
				} catch (Exception e) {
				Log.e("UDP", "S: Error", e);
				
			}
		}
		
		public void close()
		{
			socket.close();
		
		}
	}

	public class Client implements Runnable {
		private AudioRecord recorder;
		public String ServerIP; // 'Within' the emulator!
		public int ServerPort;
		InetAddress serverAddr;
		DatagramSocket socket;
		public boolean running=true;
		public Client(InetAddress severaddr, int serverPort)
		{
				
					serverAddr=severaddr;

				this.ServerPort=serverPort;
			
		}
		
		//@Override
		public void run() {
			if (running)
			try {
				// Retrieve the ServerName
				//InetAddress serverAddr = InetAddress.getByName(ServerIP);

				Log.d("UDP", "C: Connecting...");
				/* Create new UDP-Socket */
				socket = new DatagramSocket();


				/* Create UDP-packet with
				 * data & destination(url+port) */
				recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate,
						channelConfig, audioFormat, bufferSize);
				recorder.startRecording();
				while(running)
				{
				int length=recorder.read(buffer,0,bufferSize);
				Log.d("UDP", ""+length);
				Log.d("UDP", ""+bufferSize);
				DatagramPacket packet = new DatagramPacket(buffer,length, serverAddr, ServerPort);
				//Log.d("UDP", "C: Sending: '" + new String(buf) + "'");

				/* Send out the packet */
				socket.send(packet);
				Log.d("UDP", "C: Sent.");
				Log.d("UDP", "C: Done.");
				}
			} catch (Exception e) {
				Log.e("UDP", "C: Error", e);
			}
			
		}
		
		public void close()
		{
			socket.close();
		}
		
	}
}